package org.sun.sunshine.config;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * 非对称加密工具类
 * @author yusj
 */
public class SignatureUtil {

    private static final String ALGORITHM = "SHA256withRSA";

    /**
     * 生成密钥对
     * @return 密钥对
     * @throws Exception 如果生成密钥对失败
     */
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048); // 指定密钥长度
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * 将公钥转换为Base64字符串
     * @param publicKey 公钥
     * @return Base64字符串
     */
    public static String publicKeyToString(PublicKey publicKey) {
        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
    }

    /**
     * 将私钥转换为Base64字符串
     * @param privateKey 私钥
     * @return Base64字符串
     */
    public static String privateKeyToString(PrivateKey privateKey) {
        return Base64.getEncoder().encodeToString(privateKey.getEncoded());
    }

    /**
     * 从Base64字符串恢复公钥
     * @param publicKeyStr 公钥字符串
     * @return 公钥
     * @throws Exception 如果恢复公钥失败
     */
    public static PublicKey stringToPublicKey(String publicKeyStr) throws Exception {
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
        return KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(publicKeyBytes));
    }

    /**
     * 从Base64字符串恢复私钥
     * @param privateKeyStr 私钥字符串
     * @return 私钥
     * @throws Exception 如果恢复私钥失败
     */
    public static PrivateKey stringToPrivateKey(String privateKeyStr) throws Exception {
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
        return KeyFactory.getInstance(ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));
    }

    /**
     * 使用私钥对数据进行签名
     * @param data 待签名的数据
     * @param privateKey 私钥
     * @return 签名
     * @throws Exception 如果签名过程中发生错误
     */
    public static byte[] sign(byte[] data, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance(ALGORITHM);
        signature.initSign(privateKey);
        signature.update(data);
        return signature.sign();
    }

    /**
     * 使用公钥验证签名
     * @param data 待验证的数据
     * @param signature 签名
     * @param publicKey 公钥
     * @return 验证结果
     * @throws Exception 如果验证过程中发生错误
     */
    public static boolean verify(byte[] data, byte[] signature, PublicKey publicKey) throws Exception {
        Signature sig = Signature.getInstance(ALGORITHM);
        sig.initVerify(publicKey);
        sig.update(data);
        return sig.verify(signature);
    }
}

